﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public enum AttackType
{
    MeleeAttack,ChargeAttack,MagicAttack,RangeAttack
}

public struct AttackInfo
{
    public int HitPoint;
    public AttackType type;
    public Vector3 AttackOriginPos;
}

public class Warrior : BattleComponent<Warrior>
{
    [BattleComponentFieldAttr(BattleComponentFieldtype.ComponentDependent,"依赖士兵AI")]
    public SoldierAI ai;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "决定单位攻击时会有多靠近敌人")]
    public float morale;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "决定单位距离敌人多远开始准备战斗")]
    public float preparingRange;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "士兵移动判定到达的距离")]
    public float closeEnoughDistance;

    [BattleComponentFieldAttr(BattleComponentFieldtype.Preset, "近战攻击动画所需时间")]
    public float meleeAttackTime;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "判定冲锋攻击的距离")]
    public float ChargingAttakRange;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "允许冲锋攻击的角度")]
    public float ChargingAttakAngle;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "冲锋过程的最大时间")]
    public float ChargingMaxTime;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "近战攻击距离")]
    public float meleeAttackRange;
    
    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "近战攻击力")]
    public int meleeAttackPoint;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "近战攻击允许的角度")]
    public float meleeAttackAngle;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "是否能够进行远程攻击")]
    public bool ableRangedAttack;
    
    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "远程攻击的投射物种类")]
    public ProjectileType rangedAttackProjectileType;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "远程攻击时间")]
    public float rangedAttackTime;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "远程攻击从开始准备到发射的时间间隔")]
    public float rangedAttackShootTime;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "防御动画的时间")]
    public float defendTime;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "准备一次攻击所需时间")]
    public float preparingTime;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "死亡所需时间")]
    public float deathTime;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattleVolatile, "生命值")]
    public int healthPoint;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattleVolatile, "远程攻击是否已经装弹")]
    public bool rangedAttackShooted;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "防御率，化解攻击的几率")]
    public float DefendRate;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattlePersistent, "是否要持续进行远程攻击")]
    public bool ToRangeAttack;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattleVolatile, "攻击的目标")]
    public Warrior target;

    [BattleComponentFieldAttr(BattleComponentFieldtype.BattleVolatile, "近战攻击的类型")]
    public AttackType meleeAttackType;

    [BattleComponentFieldAttr(BattleComponentFieldtype.InterPhase, "累积的受伤点数")]
    public int hitPoint;

    [BattleComponentFieldAttr(BattleComponentFieldtype.InterPhase, "在下一个战斗阶段时是否发起攻击")]
    public bool toAttack;

    [BattleComponentFieldAttr(BattleComponentFieldtype.InterPhase, "在下一个战斗阶段攻击时攻击的相关信息")]
    public AttackInfo toAttackInfo;

    [BattleComponentFieldAttr(BattleComponentFieldtype.InterPhase, "在下一个战斗阶段是否进行冲锋")]
    public bool toCharge;

    [BattleComponentFieldAttr(BattleComponentFieldtype.InterPhase, "在AI更新状态时是否转入Locking状态")]
    public bool toLock;

    [BattleComponentFieldAttr(BattleComponentFieldtype.Preset, "单位归属者")]
    public PlayerType unitOwner;

    




    private void OnEnable()
    {
        Assign(this);
        WarriorManager.Instance.Enroll(this);
    }

    private void OnDisable()
    {
        Unassign(this);
        WarriorManager.Instance.Disenroll(this);
    }

    public static void UpdateSettlePhase()
    {
        foreach(var w in ComponentDataList)
        {
            w.SettlePhase();
        }
    }

    public static void UpdateBattlePhase()
    {
        foreach(var w in ComponentDataList)
        {
            w.BattlePhase();
        }
    }


    
    //战斗阶段后的结算阶段
    protected void SettlePhase()
    {
        if(hitPoint!=0)
        {
            healthPoint -= hitPoint;
            hitPoint = 0;
            if (healthPoint <= 0 && ai.currentState != SoldierState.Dead && ai.currentState != SoldierState.Locking)
            {
                ai.lockController.lockingtype = SoldierLockingtype.ToDie;
                ai.lockController.hitFlyForce = 1000 * (transform.up - transform.forward).normalized;
                toLock = true;
            }
            //if (healthPoint > 0 && ai.currentState != SoldierState.Dead && ai.currentState != SoldierState.Locking)
            //{
            //    ai.lockController.lockingtype = SoldierLockingtype.Defend;
            //    toLock = true;
            //}
        }
        
    }

    //战斗阶段
    //这一阶段只改变warrior本身上的一些特定域，例如hitPoint
    protected void BattlePhase()
    {
        if(toAttack)
        {
            target.GetHit(toAttackInfo);
            toAttack = false;
        }
    }




    public void GetHit(AttackInfo attack)
    {
        if (UnityEngine.Random.Range(0, 1) < DefendRate) return;
        hitPoint += attack.HitPoint;
        if(attack.type== AttackType.MagicAttack)
        {
            ai.lockController.lockingtype = SoldierLockingtype.HitFly;
            toLock = true;
            ai.lockController.hitFlytime = 1.0f;
            ai.lockController.hitFlyForce = 1000 * (transform.up - transform.forward).normalized;
        }
        if(attack.type== AttackType.MeleeAttack)
        {
            ai.lockController.lockingtype = SoldierLockingtype.Defend;
            toLock = true;
        }
        if(attack.type == AttackType.ChargeAttack)
        {
            ai.lockController.lockingtype = SoldierLockingtype.HitFly;
            toLock = true;
            ai.lockController.hitFlytime = 3.0f;
            ai.lockController.hitFlyForce = 1000 * (transform.up - transform.forward).normalized;
        }
    }



    public void CreatProjectile()
    {
        if (target == null) return;
        Projectile p = ProjectileManager.Instance.InstantiateProjectile(transform.position, transform.rotation, rangedAttackProjectileType);
        if (p != null)
        {
            p.pointingTarget = target.transform;
            p.warhead.target = target;
            rangedAttackShooted = true;
        }
    }
    //根据当前位置选择一个合适的战斗位置
    public Vector3 GetFihgtMove()
    {
        Vector3 delta = (target.transform.position - transform.position).normalized * meleeAttackRange * (1 - morale);
        Vector3 MoveTarget = target.transform.position - delta;
        return MoveTarget;
    }

    public bool IsTargetInPreparingRange
    {
        get { return target.transform.position.DistanceLessThan(transform.position, preparingRange); }
    }

    public bool IsaAbleMeleeAttackTarget
    {
        get { return target!=null && transform.position.DistanceLessThan(target.transform.position, meleeAttackRange)&&
                Vector3.Angle(target.transform.position - transform.position, transform.forward) < meleeAttackAngle; }
    }

    public bool IsaAbleChargeAttackTarget
    {
        get { return target != null && transform.position.DistanceLessThan(target.transform.position, ChargingAttakRange) &&
                Vector3.Angle(target.transform.position - transform.position, transform.forward) < ChargingAttakAngle; }
    }

    public bool TryMeleeAttack()
    {
        if (IsaAbleMeleeAttackTarget)
        {
            toAttackInfo = new AttackInfo()
            {
                HitPoint = meleeAttackPoint,
                type = AttackType.MeleeAttack,
                AttackOriginPos = transform.position
            };
            toAttack = true;
            return true;
        }
        return false;
    }

    public bool TryChargeAttack()
    {
        if(IsaAbleChargeAttackTarget)
        {
            toAttackInfo = new AttackInfo()
            {
                HitPoint = meleeAttackPoint,
                type = AttackType.ChargeAttack,
                AttackOriginPos = transform.position
            };
            toAttack = true;
            return true;
        }
        return false;
    }

    public void SetBetterTarget(Warrior candidate)
    {
        if (target == null ||
            !target.isActiveAndEnabled ||
            transform.position.SqrDistance(target.transform.position) > 2 * transform.position.SqrDistance(candidate.transform.position))
        {
            target = candidate;
        }
    }




}
